import configparser,os
from flask import Flask, request, jsonify, redirect, url_for, render_template, session, send_from_directory
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.middleware.proxy_fix import ProxyFix
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from models import *
from auth import *
import logging
from logging.handlers import RotatingFileHandler
from datetime import datetime

# 配置日志
def setup_logging(app):
    log_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'logs')
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    log_file = os.path.join(log_dir, 'myfunds.log')
    file_handler = RotatingFileHandler(log_file, maxBytes=10240, backupCount=10)
    file_handler.setFormatter(logging.Formatter(
        '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
    ))
    file_handler.setLevel(logging.INFO)
    app.logger.addHandler(file_handler)
    app.logger.setLevel(logging.INFO)
    app.logger.info('MyFunds startup')

# 创建应用实例
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)

# 初始化日志系统
setup_logging(app)

# 配置文件路径
config_path = os.path.join(app.root_path, 'config.cfg')
config = configparser.ConfigParser()
config.read(config_path)

# 从配置文件中获取配置项
database_path = config['APP']['DATABASE_PATH']
secret_key = config['APP']['SECRET_KEY']

# 应用配置
app.config['SECRET_KEY'] = secret_key
app.config['DATABASE_PATH'] = database_path
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{database_path}'
app.config['IMG_FOLDER'] = 'static/img/'

# 初始化Limiter
limiter = Limiter(
    key_func=get_remote_address,
    default_limits=["5 per minute"]
)

@app.before_first_request
def initialize_database():
    with app.app_context():
        # 确保数据库目录存在
        db_dir = os.path.dirname(app.config['DATABASE_PATH'])
        if not os.path.exists(db_dir):
            os.makedirs(db_dir)
            print(f"Created database directory: {db_dir}")
        
        print("Initializing database...")
        init_db(app)
        add_user_background('admin','Welcome123')

@app.route('/')
def index():
    if is_logged_in():
        funds_summary=funds_detail()[1]
        return render_template('main/account_search.html',funds_summary=funds_summary)
    else:
        return redirect(url_for('login'))

@app.route('/auth/login', methods=['GET', 'POST'])
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        app.logger.info(f'Login attempt from IP: {request.remote_addr}')
        return user_login()
    captcha = generate_captcha()
    static_img_path = os.path.join(app.static_folder, 'img', 'captcha.png')
    captcha.save(static_img_path)
    return render_template('auth/login.html', captcha_url=url_for('static', filename='img/captcha.png'))

@app.route('/refresh-captcha')
def refresh_captcha():
    captcha = generate_captcha()
    static_img_path = os.path.join(app.static_folder, 'img', 'captcha.png')
    captcha.save(static_img_path)
    # 添加 as_attachment=False 参数，确保图片在浏览器中显示而不是下载
    return send_from_directory(app.config['IMG_FOLDER'], 'captcha.png', as_attachment=False)

@app.route('/logout', methods=['POST'])
def logout():
    if is_logged_in():
        app.logger.info(f'Logout request from IP: {request.remote_addr}')
        response = user_logout()
        app.logger.info(f'Logout response: {response.get_json()}')
        return response
    else:
        app.logger.warning(f'Unauthorized logout attempt from IP: {request.remote_addr}')
        return jsonify({'message': 'Not logged in'}), 401

# 添加用户
@app.route('/add_user', methods=['POST'])
@login_required
def add_user():
    # 从请求中获取 JSON 数据
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    # 检查用户名是否已存在
    existing_user = User.query.filter_by(username=username).first()
    if existing_user:
        # 如果用户已存在，返回提示信息
        return jsonify({'message': 'User already exists'}), 409  # 409 是 Conflict 的 HTTP 状态码

    # 如果用户不存在，创建新用户
    new_user = User(username=username, password_hash=generate_password_hash(password))
    db.session.add(new_user)
    db.session.commit()
    return jsonify({'message': 'User added successfully'}), 201

# 修改用户信息
@app.route('/update_user/<int:user_id>', methods=['PUT'])
@login_required
def update_user(user_id):
    user = User.query.get(user_id)
    if not user:
        return jsonify({'message': 'User not found'}), 404
    data = request.get_json()
    if 'username' in data:
        user.username = data['username']
    if 'password' in data:
        user.set_password(data['password'])
    db.session.commit()
    return jsonify({'message': 'User updated successfully'})

# 删除用户
@app.route('/delete_user/<int:user_id>', methods=['DELETE'])
@login_required
def delete_user(user_id):
    user = User.query.get(user_id)
    if not user:
        return jsonify({'message': 'User not found'}), 404
    db.session.delete(user)
    db.session.commit()
    return jsonify({'message': 'User deleted successfully'})

@app.route('/home', methods=['GET'])
@login_required
def home():
    app.logger.info(f'User accessing home page from IP: {request.remote_addr}')
    funds_summary=funds_detail()[1]
    return render_template('main/account_search.html',funds_summary=funds_summary)

@app.route('/search_account', methods=['POST'])
@login_required
def search_account():
    funds_summary=funds_detail()[1]
    # 获取用户输入的姓名
    search_name = request.form['search_name']    
    # 根据输入的姓名查询账户信息
    account_info = jsonify(account_detail(search_name,result_type='list'))
    # 渲染模板并传递查询结果
    return account_info

@app.route('/search_NetAssetValue', methods=['GET'])
@login_required
def search_NetAssetValue():
    # 获取 URL 参数
    time_param = request.args.get('time_param')
    app.logger.info(f'Searching NetAssetValue with time_param: {time_param}')
    NetAssetValue_info = jsonify(get_NetAssetValue(time_param))
    return NetAssetValue_info

@app.route('/Trade', methods=['POST'])
@login_required
def Trade():
    date = request.form.get('date')
    name = request.form.get('name')
    money = float(request.form.get('money'))
    action = int(request.form.get('action'))
    if request.form.get('oldTotalAssets') !='':
        oldTotalAssets = float(request.form.get('oldTotalAssets'))
    else:
        oldTotalAssets=''
    ifall = request.form.get('ifall')
    info=buy_funds(date,name,money,action,oldTotalAssets,ifall)
    if info=='Success':
        return jsonify({
            'success': True,
            'message': '交易成功！'
        })
    else:
        return jsonify({
            'success': False,
            'message': '交易失败！'
        })

@app.route('/accountStatement', methods=['POST'])
@login_required
def accountStatement():
    username = request.args.get('username')    
    # 如果查询字符串中没有 'username'，则尝试从表单数据获取 'search_name'
    if not username:
        username = request.form.get('search_name')
    accountStatement = Acccount_Statement(username)  # 假设这是您的模型函数
    return  jsonify(accountStatement)

@app.route('/getDividends', methods=['POST'])
@login_required
def getDividends():
    username = request.form.get('search_name')
    persondetail=Dividends_person_detail(username)
    return  jsonify(persondetail)

@app.route('/getTotalDividends',methods=['POST','GET'])
@login_required
def getTotalDividends():
    TotalDividends=Dividends_detail()
    return  jsonify(TotalDividends)

@app.route('/setDividends', methods=['POST'])
@login_required
def setDividends():
    DividendRatio = float(request.form.get('DividendRatio'))
    date = request.form.get('date')
    info=Dividend(DividendRatio,date)
    if info=='Success':
        return jsonify({
            'success': True,
            'message': '操作成功！'
        })
    else:
        return jsonify({
            'success': False,
            'message': '操作失败！'
        })

@app.route('/setNetAssetValue',methods=['POST'])
@login_required
def setNetAssetValue():    
    TotalAssets = float(request.form.get('TotalAssets'))
    date = request.form.get('date')
    info=update_funds(TotalAssets,date)
    if info=='1':
        return jsonify({
            'success': True,
            'message': '净值更新成功！'
        })
    elif info=='2':
        return jsonify({
            'success': True,
            'message': '已是最新，无需更新！'
        })
    else:
        return jsonify({
            'success': False,
            'message': '更新失败，请联系管理员！'
        })

# 添加全局错误处理
@app.errorhandler(404)
def not_found_error(error):
    app.logger.error(f'Page not found: {request.url}')
    return render_template('errors/404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    db.session.rollback()
    app.logger.error(f'Server Error: {error}')
    return render_template('errors/500.html'), 500

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=8000)
    print()